package com.zhouxiaoxuan13.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 消费者控制器
 * 演示Spring Cloud LoadBalancer负载均衡功能
 */
@RestController
@CrossOrigin(originPatterns = "*")
public class ConsumerController {

    // 服务名称（与Consul中注册的服务名一致）
    public static final String PROMOTION_SERVICE_URL = "http://promotion-service";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WebClient.Builder webClientBuilder;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    private final AtomicLong requestCounter = new AtomicLong(0);

    /**
     * 使用RestTemplate调用促销服务 - 演示负载均衡
     */
    @GetMapping("/consumer/promotions")
    public ResponseEntity<?> getPromotions() {
        try {
            long requestNum = requestCounter.incrementAndGet();
            System.out.println("=== RestTemplate负载均衡调用 #" + requestNum + " ===");
            
            // 使用RestTemplate调用服务，LoadBalancer会自动进行负载均衡
            Object result = restTemplate.getForObject(PROMOTION_SERVICE_URL + "/api/promotions", Object.class);
            
            Map<String, Object> response = new HashMap<>();
            response.put("requestNumber", requestNum);
            response.put("data", result);
            response.put("loadBalancerType", "RestTemplate + LoadBalancer");
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("调用失败: " + e.getMessage());
        }
    }

    /**
     * 使用WebClient调用促销服务 - 演示响应式负载均衡
     */
    @GetMapping("/consumer/promotions/reactive")
    public Mono<ResponseEntity<Map<String, Object>>> getPromotionsReactive() {
        long requestNum = requestCounter.incrementAndGet();
        System.out.println("=== WebClient负载均衡调用 #" + requestNum + " ===");

        return webClientBuilder.build()
                .get()
                .uri(PROMOTION_SERVICE_URL + "/api/promotions")
                .retrieve()
                .bodyToMono(Object.class)
                .map(result -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("requestNumber", requestNum);
                    response.put("data", result);
                    response.put("loadBalancerType", "WebClient + LoadBalancer");
                    response.put("timestamp", System.currentTimeMillis());
                    return ResponseEntity.ok(response);
                })
                .onErrorReturn(ResponseEntity.status(500).body(Map.of("error", "响应式调用失败")));
    }

    /**
     * 获取服务发现信息
     */
    @GetMapping("/consumer/discovery")
    public ResponseEntity<Map<String, Object>> discovery() {
        Map<String, Object> result = new HashMap<>();
        
        // 获取所有服务
        List<String> services = discoveryClient.getServices();
        result.put("allServices", services);
        
        // 获取促销服务的所有实例
        List<ServiceInstance> instances = discoveryClient.getInstances("promotion-service");
        result.put("promotionServiceInstances", instances);
        
        System.out.println("=== 服务发现信息 ===");
        System.out.println("所有服务: " + services);
        System.out.println("促销服务实例数量: " + instances.size());
        for (ServiceInstance instance : instances) {
            System.out.println("实例: " + instance.getServiceId() + " - " + 
                             instance.getHost() + ":" + instance.getPort());
        }
        
        return ResponseEntity.ok(result);
    }

    /**
     * 手动选择服务实例 - 演示LoadBalancerClient的使用
     */
    @GetMapping("/consumer/choose-instance")
    public ResponseEntity<Map<String, Object>> chooseInstance() {
        Map<String, Object> result = new HashMap<>();
        
        // 使用LoadBalancerClient手动选择服务实例
        ServiceInstance instance = loadBalancerClient.choose("promotion-service");
        
        if (instance != null) {
            result.put("selectedInstance", instance.getHost() + ":" + instance.getPort());
            result.put("serviceId", instance.getServiceId());
            result.put("instanceId", instance.getInstanceId());
            result.put("uri", instance.getUri().toString());
            
            System.out.println("=== 手动选择的服务实例 ===");
            System.out.println("选中实例: " + instance.getHost() + ":" + instance.getPort());
        } else {
            result.put("error", "没有可用的服务实例");
        }
        
        return ResponseEntity.ok(result);
    }

    /**
     * 批量测试负载均衡效果
     */
    @GetMapping("/consumer/test-loadbalancer/{times}")
    public ResponseEntity<Map<String, Object>> testLoadBalancer(@PathVariable int times) {
        Map<String, Object> result = new HashMap<>();
        Map<String, Integer> instanceCounts = new HashMap<>();
        
        System.out.println("=== 开始批量负载均衡测试，共" + times + "次 ===");
        
        for (int i = 0; i < times; i++) {
            try {
                // 使用LoadBalancerClient选择实例
                ServiceInstance instance = loadBalancerClient.choose("promotion-service");
                if (instance != null) {
                    String instanceKey = instance.getHost() + ":" + instance.getPort();
                    instanceCounts.put(instanceKey, instanceCounts.getOrDefault(instanceKey, 0) + 1);
                    System.out.println("第" + (i + 1) + "次选择: " + instanceKey);
                }
            } catch (Exception e) {
                System.err.println("第" + (i + 1) + "次选择失败: " + e.getMessage());
            }
        }
        
        result.put("totalTests", times);
        result.put("instanceDistribution", instanceCounts);
        result.put("timestamp", System.currentTimeMillis());
        
        System.out.println("=== 负载均衡测试结果 ===");
        System.out.println("实例分布: " + instanceCounts);
        
        return ResponseEntity.ok(result);
    }

    /**
     * 调用LoadBalancer专用测试端点
     */
    @GetMapping("/consumer/loadbalancer/current-instance")
    public ResponseEntity<?> getCurrentInstance() {
        try {
            long requestNum = requestCounter.incrementAndGet();
            System.out.println("=== 调用LoadBalancer测试端点 #" + requestNum + " ===");
            
            Object result = restTemplate.getForObject(
                PROMOTION_SERVICE_URL + "/api/loadbalancer/current-instance", 
                Object.class
            );
            
            Map<String, Object> response = new HashMap<>();
            response.put("consumerRequestNumber", requestNum);
            response.put("providerResponse", result);
            response.put("loadBalancerType", "Spring Cloud LoadBalancer");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("调用LoadBalancer测试端点失败: " + e.getMessage());
        }
    }
}
